#ifndef _VECTOR3D_H_
#define _VECTOR3D_H_

#include <math.h>
#include <gccore.h>

class Vector3D {
public:
	Vector3D() {
		x = 0.0f; 
		y = 0.0f; 
		z = 0.0f;
	};

	Vector3D(float pX, float pY, float pZ) {
		x = pX; 
		y = pY; 
		z = pZ;
	};
	
	void Zero() {
		x = 0.0f; 
		y = 0.0f;
		z = 0.0f;
	};

	float Length() {
		return sqrtf(x*x + y*y + z*z); 
	};

	float Dist(Vector3D &op2) { 
		return sqrtf(DistSquared(op2) ); 
	};

	float DistSquared(Vector3D &op2) { 
		return (op2.x - x)*(op2.x - x) + (op2.y - y)*(op2.y - y) + (op2.z - z)*(op2.z - z); 
	};
	
	//Produit Scalaire
	float DotProduct(Vector3D &op2) { 
		return (x * op2.x + y * op2.y + z * op2.z); 
	};
	
	//Produit Vectoriel
	static Vector3D CrossProduct(Vector3D op1, Vector3D op2) {
		return Vector3D((op1.y*op2.z) - (op1.z*op2.y), (op1.z*op2.x) - (op1.x*op2.z), (op1.x*op2.y) - (op1.y*op2.x));
	};

	void Normalize() {
		float size = Length();
		if(size != 0)
			*this /= size;
		else
			Zero();
	};

	//Conversion vers les formats de GX
	guVector toGuVector() {
		guVector temp = {x, z, y};
		return temp;
	}

	Vector3D operator+(Vector3D op2) { return Vector3D(x + op2.x, y + op2.y, z + op2.z); };
	Vector3D operator-(Vector3D op2) { return Vector3D(x - op2.x, y - op2.y, z - op2.z); };
	Vector3D operator*(float scale) { return Vector3D(x*scale, y*scale, z*scale); };
	Vector3D operator/(float scale) { return Vector3D(x/scale, y/scale, z/scale); };
	
	void operator=(Vector3D op2) {x = op2.x; y = op2.y; z = op2.z; };
	void operator+=(Vector3D op2) {x += op2.x; y += op2.y; z += op2.z; };
	void operator+=(float scale) {x += scale; y += scale; z += scale; };
	void operator-=(Vector3D op2) {x -= op2.x; y -= op2.y; z -= op2.z; };
	void operator-=(float scale) {x -= scale; y -= scale; z -= scale; };
	void operator*=(Vector3D op2) {x = x*op2.x; y = y*op2.y; z = z*op2.z; };
	void operator*=(float scale) {x = x*scale; y = y*scale; z = z*scale; };
	void operator/=(Vector3D op2) {x = x/op2.x; y = y/op2.y; z = z/op2.z; };
	void operator/=(float scale) {x = x/scale; y = y/scale; z = z/scale; };

	bool operator==(Vector3D &op2) { return (x == op2.x && y == op2.y && z == op2.z); };
	bool operator!=(Vector3D &op2) { return (x != op2.x || y != op2.y || z != op2.z); };

public:
	float x, y, z;
};

#endif
